package com.puppet.config;

import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/*
* 开启消息生产者信息确认：
*   1、消息到达交换机的确认：setConfirmCallback
*   2、消息从交换机到队列失败的确认：setReturnCallback
 * */
@Configuration
public class RabbitConfig {

    /*
    * 修改RabbitTemplate对象的配置
    * */
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        //开启消息强制投递
        rabbitTemplate.setMandatory(true);
        //消息到达交换机的确认回调：写熟了在用lambda表达式
        //消息到达交换机的确认回调函数
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ask, String cause) {
                System.out.println("消息数据：" + correlationData);
                System.out.println("ask==应答：" + ask);
                System.out.println("当ask为false时，获取错误原因：" + cause);
                if (ask) {
                    System.out.println("消息已到达交换机");
                } else {
                    System.out.println("消息未到达交换机，原因是：" + cause);
                /*后续的操作：
                   第一种、因为网络的原因，继续重发信息
                   第二种、把信息存入到消息表中，该表有主键、消息id、消息内容等，在根据这个表去做业务
                 */
                }
            }
        });

        //消息从交换机路由到队列失败的确认回调函数
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {

            @Override
            public void returnedMessage(ReturnedMessage returned) {
                System.out.println("消息内容" + returned.getMessage());
                System.out.println("交换机" + returned.getExchange());
                System.out.println("响应码" + returned.getReplyCode());
                System.out.println("响应文本" + returned.getReplyText());
                System.out.println("路由键" + returned.getRoutingKey());
                //在这里也可以进行后续操作
            }
        });
        return rabbitTemplate;
    }


}
